package com.ruoyi.eqmonitor.utils;

import com.ruoyi.eqmonitor.dispose.dtos.SiteMonitorDataGetAllDto;
import lombok.Getter;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 常量与枚举表
 *
 * @author dh
 */
public class Constant {

    public static final String TRUE = "0";
    public static final String FALSE = "1";

    /**
     * mqtt硬件类型: GW: 网关类设备(网关下带若干个采集器设备), ND: 采集器设备
     */
    public static final String[] MQTT_HARDWARE_TYPES = {"GW", "ND"};

    /**
     * 分类每种监测指标的检测项
     * @see MonitorInfo
     */
    private static final Map<MqttMsgType, Map<String, MonitorInfo>> GROUP_PARAMETER_TYPE_MAPPING;
    static {
        GROUP_PARAMETER_TYPE_MAPPING = Arrays.stream(MonitorInfo.values()).collect(Collectors.groupingBy(MonitorInfo::getParameterType, Collectors.toMap(MonitorInfo::getCode, Function.identity())));
    }

    /**
     * mqtt推送的消息类型
     */
    @Getter
    public enum MqttMsgType {
        /** 设备参数 */
        PARAMETER(1),
        /** 监测数据 */
        MONITOR_DATA(2),
        /** 告警数据 */
        ALARM(3),
        /** 自定义 */
        CUSTOM(999);

        private int code;

        private MqttMsgType(int code) {
            this.code = code;
        }
    }

    /**
     * 采集项枚举
     * 使用方法:
     *  1. 枚举字段说明
     *      code: 采集项编码, 恒星物联文档提供
     *      name: 采集项名称, 恒星物联文档提供
     *      unit: 采集项单位, 恒星物联文档提供(部分是自己重写重定义的, 如液位高度)
     *      parameterType: 采集项类型, 用于区分采集项的类型, 如设备参数, 监测数据, 告警数据等 {@link MqttMsgType}恒星物联文档提供
     *      isSave: 是否保存到数据库, 用于区分是否需要保存到数据库, 如 告警数据等不需要保存到数据库
     *  2. 修改此值需要同步修改管理后台字典: 设备监测指标 opt_device_monitor_quota 强关联
     *  3. 使用此枚举的地方: 后台设备数据解析, 后台设备数据查询
     *  4. 使用前台字典的地方: 基本所有能看到设备数据的地方均在使用, pc, 大屏, app
     *  5. 规律: 此枚举的命名方式按照设备传递的数据类型区分, 如设备参数前缀为P_,监测数据为M_,告警数据为A_,自定义数据为C_开头
     */
    @Getter
    public enum MonitorInfo {
        // ---------------------------------设备参数开始---------------------------------
        P_0x000B("0x000B", "硬件版本", null, MqttMsgType.PARAMETER),
        P_0x0002("0x0002", "软件版本", null, MqttMsgType.PARAMETER),
        P_0x0005("0x0005", "设备地址", null, MqttMsgType.PARAMETER),
        // 固定为9 井盖状态监测仪
        P_0x0019("0x0019", "产品类型", null, MqttMsgType.PARAMETER),
        P_0x0028("0x0028", "预警高度", "mm", MqttMsgType.PARAMETER),
        P_0x0029("0x0029", "告警高度", "mm", MqttMsgType.PARAMETER),
        P_0x002A("0x002A", "预警采集周期", "秒", MqttMsgType.PARAMETER),
        P_0x002B("0x002B", "预警上传周期", "秒", MqttMsgType.PARAMETER),
        P_0x002C("0x002C", "告警采集周期", "秒", MqttMsgType.PARAMETER),
        P_0x002D("0x002D", "告警上传周期", "秒", MqttMsgType.PARAMETER),
        P_0x0105("0x0105", "日累积雨量开始时间", "h", MqttMsgType.PARAMETER),
        P_0x0110("0x0110", "液位传感测量量程上限值", "mm", MqttMsgType.PARAMETER),
        P_0x0111("0x0111", "液位传感测量量程下限值", "mm", MqttMsgType.PARAMETER),
        // 0x01圆形, 0x02方形, 0x03梯形
        P_0x0112("0x0112", "截面形状", null, MqttMsgType.PARAMETER),
        P_0x0113("0x0113", "截面直径", "cm", MqttMsgType.PARAMETER),
        P_0x0118("0x0118", "高度补偿", "cm", MqttMsgType.PARAMETER),
        P_0x013A("0x013A", "ICCID", null, MqttMsgType.PARAMETER),
        P_0x013C("0x013C", "信号强度", null, MqttMsgType.PARAMETER),
        P_0x0165("0x0165", "电池电量", "%", MqttMsgType.PARAMETER, true),
        P_0x0294("0x0294", "电导率告警上限", "us/cm", MqttMsgType.PARAMETER),
        P_0x0295("0x0295", "电导率告警下限", "us/cm", MqttMsgType.PARAMETER),
        P_0x0297("0x0297", "COD告警上限", "mg/L", MqttMsgType.PARAMETER),
        P_0x0298("0x0298", "COD告警下限", "mg/cm", MqttMsgType.PARAMETER),
        P_0x0299("0x0299", "氨氮告警上限", "mg/L", MqttMsgType.PARAMETER),
        P_0x029A("0x029A", "氨氮告警下限", "mg/L", MqttMsgType.PARAMETER),
        P_0x0401("0x0401", "采集周期", "秒", MqttMsgType.PARAMETER),
        P_0x0402("0x0402", "上传周期", "°", MqttMsgType.PARAMETER),
        P_0x0404("0x0404", "设备时间", null, MqttMsgType.PARAMETER),
        P_0x06B0("0x06B0", "井盖倾角", "°", MqttMsgType.PARAMETER, true),
        // 0.关,1.开
        P_0x06B1("0x06B1", "井盖状态", null, MqttMsgType.PARAMETER),
        P_0x06B2("0x06B2", "开盖报警倾角阈值", "°", MqttMsgType.PARAMETER),
        // 1.打开,0.关闭
        P_0x06BA("0x06BA", "自动校零功能开关", null, MqttMsgType.PARAMETER),
        // 1.布放,0.撤防
        P_0x06B6("0x06B6", "布防功能开关", null, MqttMsgType.PARAMETER),
        P_0x06BD("0x06BD", "X零点值", null, MqttMsgType.PARAMETER),
        P_0x06BE("0x06BE", "Y零点值", null, MqttMsgType.PARAMETER),
        P_0x06C0("0x06C0", "告警次数限制值", null, MqttMsgType.PARAMETER),
        // 1.正常,2满溢
        P_0x06C3("0x06C3", "满溢状态", null, MqttMsgType.PARAMETER),
        P_0x1306("0x1306", "4G通道上传周期", "秒", MqttMsgType.PARAMETER),
        P_0x1307("0x1307", "以太网通道上传周期", "秒", MqttMsgType.PARAMETER),
        P_0x013CA("0x013CA", "误码率", null, MqttMsgType.PARAMETER),
        // ---------------------------------设备参数结束---------------------------------


        // ---------------------------------监测数据开始---------------------------------
        /** 设备实时电压 默认上下限为20~30 */
        M_0x0501("0x0501", "设备实时电压", "V", MqttMsgType.MONITOR_DATA, true),
        /** 温度 默认上下限为40~50 */
        M_0x0502("0x0502", "温度", "℃", MqttMsgType.MONITOR_DATA, true),
        /** 压力 */
        M_0x0510("0x0510", "压力", "KPA", MqttMsgType.MONITOR_DATA, true),
        /** 浊度 默认上下限为100~10 */
        M_0x0520("0x0520", "浊度", "NTU", MqttMsgType.MONITOR_DATA, true),
        /** 余氯 */
        M_0x0521("0x0521", "余氯", "mg/L", MqttMsgType.MONITOR_DATA, true),
        /** ph */
        M_0x0522("0x0522", "PH值", "", MqttMsgType.MONITOR_DATA, true),
        /** 电导率 默认上下限为10~0.2 */
        M_0x0523("0x0523", "电导率", "mS/cm", MqttMsgType.MONITOR_DATA, true),
        /** COD 默认出水标准不大于50mg/L */
        M_0x0527("0x0527", "COD", "mg/L", MqttMsgType.MONITOR_DATA, true),
        /** 氨氮 默认出水标准不大于5mg/L */
        M_0x0528("0x0528", "氨氮", "mg/L", MqttMsgType.MONITOR_DATA, true),
        /** 24小时雨量 默认不大于100mm TODO 此处没有参照,临时规定 */
        M_0x0566("0x0566", "24小时雨量", "mm", MqttMsgType.MONITOR_DATA, true),
        /** 当天降雨量 */
        M_0x0567("0x0567", "当天降雨量", "mm", MqttMsgType.MONITOR_DATA, true),
        /** 瞬时降雨量 */
        M_0x0568("0x0568", "瞬时降雨量", "mm", MqttMsgType.MONITOR_DATA, true),
        /** 总降雨量 */
        M_0x0569("0x0569", "总降雨量", "mm", MqttMsgType.MONITOR_DATA, true),
        /** 小时降雨量 */
        M_0x056A("0x056A", "小时降雨量", "mm", MqttMsgType.MONITOR_DATA, true),
        /** 上小时降雨量 */
        M_0x056B("0x056B", "上小时降雨量", "mm", MqttMsgType.MONITOR_DATA, true),
        /** 累积雨量 默认不大于500mm */
        M_0x056F("0x056F", "累积雨量", "mm", MqttMsgType.MONITOR_DATA, false),
        /** 正向累积流量 */
        M_0x0590("0x0590", "正向累积流量", "m³", MqttMsgType.MONITOR_DATA, true),
        /** 瞬时流量 默认不大于15m3/s  */
        M_0x0592("0x0592", "瞬时流量", "m3/s", MqttMsgType.MONITOR_DATA, true),
        /** 流速 默认上下限为0.2~2.5 */
        M_0x0593("0x0593", "流速", "m/s", MqttMsgType.MONITOR_DATA, true),
        /** 液位高度 默认不大于350cm */
        M_0x05D1("0x05D1", "液位高度", "m", MqttMsgType.MONITOR_DATA, true),
        /** 液位状态 0: 正常 1: 预警 2: 告警 TODO 暂时不报警 */
        M_0x05E0("0x05E0", "液位状态", null, MqttMsgType.MONITOR_DATA),
        /** 电池电量 默认不小于10 */
        M_0x6500("0x6500", "电池电量", "%", MqttMsgType.MONITOR_DATA, true),
        /** COD状态 0: 正常 1: 预警 2: 告警 TODO 暂时不报警 */
        M_0x6588("0x6588", "COD状态", null, MqttMsgType.MONITOR_DATA, false),
        /** 电导率状态 0: 正常 1: 预警 2: 告警 TODO 暂时不报警 */
        M_0x6589("0x6589", "电导率状态", null, MqttMsgType.MONITOR_DATA, false),
        /** 氨氮状态 0: 正常 1: 预警 2: 告警 TODO 暂时不报警 */
        M_0x658B("0x658B", "氨氮状态", null, MqttMsgType.MONITOR_DATA, false),
        /** 垂直角度 TODO 不知道代表什么 暂时不报警 */
        M_0x6597("0x6597", "垂直角度", "°", MqttMsgType.MONITOR_DATA, true),
        /** 空高值 TODO 不知道代表什么 暂时不报警 */
        M_0x6598("0x6598", "空高值", "m", MqttMsgType.MONITOR_DATA, true),
        // ---------------------------------监测数据结束---------------------------------

        // ---------------------------------报警数据结束---------------------------------
        // 1.故障上报, 0.故障解除
        A_0x020A("0x020A", "通信故障", null, MqttMsgType.ALARM),
        A_0x0204("0x0204", "低电量告警", null, MqttMsgType.ALARM),
        A_0x0220("0x0220", "液位超上限告警", null, MqttMsgType.ALARM),
        A_0x0294("0x0294", "电导率超上限告警", null, MqttMsgType.ALARM),
        A_0x0295("0x0295", "电导率下限告警", null, MqttMsgType.ALARM),
        A_0x0297("0x0297", "COD超上限告警", null, MqttMsgType.ALARM),
        A_0x0298("0x0298", "COD低下限告警", null, MqttMsgType.ALARM),
        A_0x0299("0x0299", "氨氮超上限告警", null, MqttMsgType.ALARM),
        A_0x029A("0x029A", "氨氮低下限告警", null, MqttMsgType.ALARM),
        // 1.角度告警, 2.位移告警, 3.强震动告警
        A_0x0312("0x0312", "井盖异动告警", null, MqttMsgType.ALARM),
        // 1.正常, 2.告警, 3.告警恢复
        A_0x06C3("0x06C3", "满溢状态告警", null, MqttMsgType.ALARM),
        // ---------------------------------报警数据结束---------------------------------

        // ---------------------------------自定义数监测指标开始---------------------------------
        /** 日累计流量 */
        C_CC0001("CC0001", "日累计流量", "m³/d", MqttMsgType.CUSTOM,true),
        /** COD日均值 */
        C_CC0002("CC0002", "COD日均值", "mg/L", MqttMsgType.CUSTOM,true),
        /** 氨氮日均值 */
        C_CC0003("CC0003", "氨氮日均值", "mg/L", MqttMsgType.CUSTOM,true),
        /** COD日排放量 */
        C_CC0004("CC0004", "COD日排放量", "kg/d", MqttMsgType.CUSTOM,true),
        /** 氨氮日排放量 */
        C_CC0005("CC0005", "氨氮日排放量", "kg/d", MqttMsgType.CUSTOM,true),
        /** 电导率日均值 */
        C_CC0006("CC0006", "电导率日均值", "mS/cm", MqttMsgType.CUSTOM,true),
        /** 液位高度日均值 */
        C_CC0007("CC0007", "液位高度日均值", "m", MqttMsgType.CUSTOM,true),
        /** 日累计雨量(和24小时雨量是一个东西, 主要是为了和其他日统计的监测指标放在一起) */
        C_CC0008("CC0008", "日累计雨量", "mm", MqttMsgType.CUSTOM,true);
        // ---------------------------------自定义数监测指标结束---------------------------------

        /** 编码 */
        private String code;
        /** 名称 */
        private String name;
        /** 单位 */
        private String unit;
        /** 参数类型 */
        private MqttMsgType parameterType;
        /** 是否存储 */
        private boolean isSave;

        /**
         * 不需要存储的参数 构造
         */
        private MonitorInfo(String code, String name, String unit, MqttMsgType mqttMsgType) {
            this.code = code;
            this.name = name;
            this.unit = unit;
            this.parameterType = mqttMsgType;
            this.isSave = false;
        }

        /**
         * 需要存储的参数 构造
         */
        private MonitorInfo(String code, String name, String unit, MqttMsgType mqttMsgType, boolean isSave) {
            this.code = code;
            this.name = name;
            this.unit = unit;
            this.parameterType = mqttMsgType;
            this.isSave = isSave;
        }

        /** 根据编码获取参数指标详情 */
        public static MonitorInfo getParamInfoByCode(String code) {
            return getInfoByCodeAndType(code, MqttMsgType.PARAMETER);
        }
        /** 根据编码获取监测指标详情 */
        public static MonitorInfo getMonitorInfoByCode(String code) {
            return getInfoByCodeAndType(code, MqttMsgType.MONITOR_DATA);
        }
        /** 根据编码获取报警指标详情 */
        public static MonitorInfo getAlarmInfoByCode(String code) {
            return getInfoByCodeAndType(code, MqttMsgType.ALARM);
        }
        /** 根据编码获取报警指标详情 */
        public static MonitorInfo getCustomInfoByCode(String code) {
            return getInfoByCodeAndType(code, MqttMsgType.CUSTOM);
        }
        /** 根据编码与类型获取监测指标明细 */
        public static MonitorInfo getInfoByCodeAndType(String code, MqttMsgType mqttMsgType) {
            if (mqttMsgType == null) {
                throw new IllegalArgumentException("监测类型不能为空");
            }
            Map<String, MonitorInfo> typeMap = GROUP_PARAMETER_TYPE_MAPPING.get(mqttMsgType);
            if (typeMap == null) {
                return null;
            } else {
                return typeMap.get(code);
            }
        }

        public static MonitorInfo getInfoByCode(String code) {
            MonitorInfo result = null;
            for (Map<String, MonitorInfo> value : GROUP_PARAMETER_TYPE_MAPPING.values()) {
                MonitorInfo info = value.get(code);
                if (info != null) {
                    result = info;
                    /*
                     * 这里判断下是不是 设备参数 不是则直接返回
                     * 如果是设备参数 因为设备参数有几个和监测指标一样的数据 则先向后遍历 如果在监测指标中找到, 就返回监测指标的值
                     */
                    if (MqttMsgType.PARAMETER.equals(info.getParameterType())) {
                        return result;
                    }
                }
            }
            return result;
        }

    }

    /**
     * 设备类型
     * !!修改此枚举需要注意下方关联枚举!!
     * [
     *  一杆式内涝监测站,
     *  井盖状态监测仪,
     *  管道流量监测仪,
     *  流量水质（氨氮）一体机,
     *  原位水质监测仪（COD+氨氮）,
     *  原位水质监测仪（电导率+液位）,
     *  原位水质监测仪（COD+液位）,
     *  窨井液位监测仪
     * ]
     */
    @Getter
    public enum EquipmentType {
        /** 一杆式内涝监测站 */
        SE200_L_Y0("SE200-L-Y0", "雨量计"),
        /** 井盖状态监测仪 */
        SJ300_N_D2("SJ300-N-D2", "车辆状态监测仪"),
        /** 供水水质监测仪 */
        SW300("SW300", "供水水质监测仪"),
        /** 排水液位监测仪 */
        SY800_L_Y0("SY800-L-Y0", "排水管网流量监测+液位监测仪"),
        /** 排水流量监测仪 */
        SR500_L_Y0_LD("SR500-L-Y0-LD", "排水流量监测仪"),
        /** 供水流量监测仪 */
        SR500_N_D2_LD("SR500-N-D2-LD", "积水流量监测仪"),
        SR500_L_Y0_SNY("SR500-L-Y0-SNY", "排水管网水质监测仪（浊度+COD+氨氮）");
        /** 流量水质（氨氮）一体机 *//*
        SR500_L_Y0_LDN("SR500-L-Y0-LDN", "流量水质（氨氮）一体机"),
        *//** 原位水质监测仪（COD+氨氮） *//*
        SR500_L_Y0_SNY("SR500-L-Y0-SNY", "原位水质监测仪（COD+氨氮）"),
        *//** 原位水质监测仪（电导率+液位） *//*
        SR500_L_Y0_STE("SR500-L-Y0-STE", "原位水质监测仪（电导率+液位）"),
        *//** 原位水质监测仪（COD+液位） *//*
        SR500_L_Y0_SYT("SR500-L-Y0-SYT", "原位水质监测仪（COD+液位）"),
        *//** 雷达流量计 *//*
        SE500_L_Y0("SE500-L-Y0","雷达流量计"),
        *//** 窨井液位监测仪 *//*
        SY800_L_Y0("SY800-L-Y0", "窨井液位监测仪");*/

        private String code;
        private String value;

        public static String getValueByCode(String code) {
            for (EquipmentType type : EquipmentType.values()) {
                if (type.getCode().equals(code)) {
                    return type.getValue();
                }
            }
            return null;
        }

        private EquipmentType(String code, String value) {
            this.code = code;
            this.value = value;
        }

    }

    /**
     * 设备类型与对应监测指标关联关系
     */
    @Getter
    public enum EquipmentTypeMonitorInfo {
        /** 一杆式内涝监测站 */
        SE200_L_Y0(EquipmentType.SE200_L_Y0.getCode(),
                // 系统参数
               // MonitorInfo.P_0x0002, MonitorInfo.P_0x013A, MonitorInfo.P_0x013C, MonitorInfo.P_0x1306,
                //MonitorInfo.P_0x1307, MonitorInfo.P_0x0005, MonitorInfo.P_0x0105, MonitorInfo.P_0x0401,
                // 采集数据
                //MonitorInfo.M_0x0501,
                //MonitorInfo.M_0x0566
                MonitorInfo.M_0x0567
                //MonitorInfo.M_0x0568,
                //MonitorInfo.M_0x0569,
                //MonitorInfo.M_0x056A,
                //MonitorInfo.M_0x056B
                //MonitorInfo.M_0x6500
                //MonitorInfo.M_0x056F,
                //MonitorInfo.M_0x6598,
               // MonitorInfo.M_0x0590, MonitorInfo.M_0x0592, MonitorInfo.M_0x0593,
                //MonitorInfo.M_0x6500, MonitorInfo.M_0x6597,
                // 告警
                //MonitorInfo.A_0x020A,
                // 自定义
               // MonitorInfo.C_CC0001, MonitorInfo.C_CC0007, MonitorInfo.C_CC0008
        ),

        /** 井盖状态监测仪 */
        SJ300_N_D2(EquipmentType.SJ300_N_D2.getCode(),
                // 系统参数
                //MonitorInfo.P_0x0002, MonitorInfo.P_0x013A, MonitorInfo.P_0x013C, MonitorInfo.P_0x0402,
                //MonitorInfo.P_0x06B2,
                MonitorInfo.P_0x06B0, MonitorInfo.P_0x06B1
                //MonitorInfo.P_0x0404,
                //MonitorInfo.P_0x0019, MonitorInfo.P_0x0165, MonitorInfo.P_0x06BA, MonitorInfo.P_0x06B6,
                //MonitorInfo.P_0x06BD, MonitorInfo.P_0x06BE, MonitorInfo.P_0x06C0, MonitorInfo.P_0x06C3,
                // 采集数据
                //MonitorInfo.M_0x0502, MonitorInfo.M_0x0501,
                // 告警
                //MonitorInfo.A_0x0312, MonitorInfo.A_0x0204, MonitorInfo.A_0x06C3
        ),
        /** 供水水质监测仪 */
        SW300(EquipmentType.SW300.getCode(),
                // 系统参数
                //MonitorInfo.P_0x000B, MonitorInfo.P_0x0002, MonitorInfo.P_0x013A, MonitorInfo.P_0x013C,
                //MonitorInfo.P_0x013CA, MonitorInfo.P_0x0118, MonitorInfo.P_0x0112, MonitorInfo.P_0x0113,
                //MonitorInfo.P_0x0165, MonitorInfo.P_0x0404, MonitorInfo.P_0x0028, MonitorInfo.P_0x0029,
                //MonitorInfo.P_0x0401, MonitorInfo.P_0x0402, MonitorInfo.P_0x002A, MonitorInfo.P_0x002B,
                //MonitorInfo.P_0x002C, MonitorInfo.P_0x002D,
                // 采集数据
                MonitorInfo.M_0x0502, MonitorInfo.M_0x0520, MonitorInfo.M_0x0521,
                MonitorInfo.M_0x0522,MonitorInfo.M_0x0523//, MonitorInfo.M_0x0593,
                // 告警
                //MonitorInfo.A_0x0204, MonitorInfo.A_0x0220,
                // 自定义
               //MonitorInfo.C_CC0001
                //, MonitorInfo.C_CC0007
        ),
        /** 排水管网流量监测+液位监测仪 */
        SY800_L_Y0(EquipmentType.SY800_L_Y0.getCode(),
                // 系统参数
                //MonitorInfo.P_0x000B, MonitorInfo.P_0x0002, MonitorInfo.P_0x013A, MonitorInfo.P_0x013C,
                //MonitorInfo.P_0x013CA, MonitorInfo.P_0x0110, MonitorInfo.P_0x0111, MonitorInfo.P_0x0165,
                //MonitorInfo.P_0x0404, MonitorInfo.P_0x0028, MonitorInfo.P_0x0029, MonitorInfo.P_0x0401,
               //MonitorInfo.P_0x0402, MonitorInfo.P_0x002A, MonitorInfo.P_0x002B, MonitorInfo.P_0x002C,
                //MonitorInfo.P_0x002D,
                // 采集数据
                MonitorInfo.M_0x05D1,
                MonitorInfo.M_0x0593,
                MonitorInfo.M_0x0502,
                MonitorInfo.M_0x0592,
//                MonitorInfo.M_0x0590
                //MonitorInfo.M_0x05E0,
                //MonitorInfo.M_0x0501
                // 告警
                //MonitorInfo.A_0x0204, MonitorInfo.A_0x0220,
                // 自定义
                MonitorInfo.C_CC0001//, MonitorInfo.C_CC0007
        ),
        /** 排水流量监测仪 */
        SR500_L_Y0_LD(EquipmentType.SR500_L_Y0_LD.getCode(),
                // 系统参数
                //MonitorInfo.P_0x000B, MonitorInfo.P_0x0002, MonitorInfo.P_0x013A, MonitorInfo.P_0x013C,
                //MonitorInfo.P_0x013CA, MonitorInfo.P_0x0118, MonitorInfo.P_0x0112, MonitorInfo.P_0x0113,
                //MonitorInfo.P_0x0165, MonitorInfo.P_0x0404, MonitorInfo.P_0x0028, MonitorInfo.P_0x0029,
                //MonitorInfo.P_0x0401, MonitorInfo.P_0x0402, MonitorInfo.P_0x002A, MonitorInfo.P_0x002B,
                //MonitorInfo.P_0x002C, MonitorInfo.P_0x002D,
                // 采集数据
                MonitorInfo.M_0x0502, MonitorInfo.M_0x0593, MonitorInfo.M_0x0592, MonitorInfo.M_0x0501,
                MonitorInfo.M_0x05D1//,MonitorInfo.M_0x0523//,
                // 告警
                //MonitorInfo.A_0x0204, MonitorInfo.A_0x0220,
                // 自定义
                //MonitorInfo.C_CC0001
                //, MonitorInfo.C_CC0007
        ),

        /** 道路积水监测仪 */
        SR500_N_D2_LD(EquipmentType.SR500_N_D2_LD.getCode(),
            // 系统参数
            //MonitorInfo.P_0x000B, MonitorInfo.P_0x0002, MonitorInfo.P_0x013A, MonitorInfo.P_0x013C,
            //MonitorInfo.P_0x013CA, MonitorInfo.P_0x0118, MonitorInfo.P_0x0112, MonitorInfo.P_0x0113,
            //MonitorInfo.P_0x0165, MonitorInfo.P_0x0404, MonitorInfo.P_0x0028, MonitorInfo.P_0x0029,
            //MonitorInfo.P_0x0401, MonitorInfo.P_0x0402, MonitorInfo.P_0x002A, MonitorInfo.P_0x002B,
            //MonitorInfo.P_0x002C, MonitorInfo.P_0x002D,
            // 采集数据
            MonitorInfo.M_0x0501,
            MonitorInfo.M_0x05D1,
            MonitorInfo.M_0x6500
            //MonitorInfo.M_0x05D1//,MonitorInfo.M_0x0523//,
            // 告警
            //MonitorInfo.A_0x0204, MonitorInfo.A_0x0220,
            // 自定义
            //MonitorInfo.C_CC0001
            //, MonitorInfo.C_CC0007
        ),
        /** 排水管网水质监测仪（浊度+COD+氨氮）*/
        SR500_L_Y0_SNY(EquipmentType.SR500_L_Y0_SNY.getCode(),
                // 系统参数
//                MonitorInfo.P_0x000B, MonitorInfo.P_0x0002, MonitorInfo.P_0x013A, MonitorInfo.P_0x013C,
//                MonitorInfo.P_0x013CA, MonitorInfo.P_0x0297, MonitorInfo.P_0x0298, MonitorInfo.P_0x0165,
//                MonitorInfo.P_0x0404, MonitorInfo.P_0x0401, MonitorInfo.P_0x0402, MonitorInfo.P_0x0299,
//                MonitorInfo.P_0x029A,
                // 采集数据
                MonitorInfo.M_0x0502,
                MonitorInfo.M_0x0520,
                //MonitorInfo.M_0x0501,
                MonitorInfo.M_0x0528,
                MonitorInfo.M_0x0527
                // 告警
//                MonitorInfo.A_0x0204, MonitorInfo.A_0x0297, MonitorInfo.A_0x0298, MonitorInfo.A_0x0299,
//                MonitorInfo.A_0x029A,
                // 自定义
                //MonitorInfo.C_CC0002, MonitorInfo.C_CC0003
        )
        ;

       /* *//** 流量水质（氨氮）一体机 *//*
        SR500_L_Y0_LDN(EquipmentType.SR500_L_Y0_LDN.getCode(),
                // 系统参数
                MonitorInfo.P_0x000B, MonitorInfo.P_0x0002, MonitorInfo.P_0x013A, MonitorInfo.P_0x013C,
                MonitorInfo.P_0x013CA, MonitorInfo.P_0x0118, MonitorInfo.P_0x0112, MonitorInfo.P_0x0113,
                MonitorInfo.P_0x0299, MonitorInfo.P_0x029A, MonitorInfo.P_0x0165, MonitorInfo.P_0x0404,
                MonitorInfo.P_0x0028, MonitorInfo.P_0x0029, MonitorInfo.P_0x0401, MonitorInfo.P_0x0402,
                MonitorInfo.P_0x002A, MonitorInfo.P_0x002B, MonitorInfo.P_0x002C, MonitorInfo.P_0x002D,
                // 采集数据
                MonitorInfo.M_0x0502, MonitorInfo.M_0x0501, MonitorInfo.M_0x05E0, MonitorInfo.M_0x658B,
                MonitorInfo.M_0x0590, MonitorInfo.M_0x0593, MonitorInfo.M_0x05D1, MonitorInfo.M_0x0528,
                MonitorInfo.M_0x0592,
                // 告警
                MonitorInfo.A_0x0204, MonitorInfo.A_0x0297, MonitorInfo.A_0x0298, MonitorInfo.A_0x0220,
                // 自定义
                MonitorInfo.C_CC0001, MonitorInfo.C_CC0003, MonitorInfo.C_CC0007
        ),

        */

        /** 原位水质监测仪（电导率+液位） *//*
        SR500_L_Y0_STE(EquipmentType.SR500_L_Y0_STE.getCode(),
                // 系统参数
                MonitorInfo.P_0x000B, MonitorInfo.P_0x0002, MonitorInfo.P_0x013A, MonitorInfo.P_0x013C,
                MonitorInfo.P_0x013CA, MonitorInfo.P_0x0118, MonitorInfo.P_0x0294, MonitorInfo.P_0x0295,
                MonitorInfo.P_0x0110, MonitorInfo.P_0x0165, MonitorInfo.P_0x0404, MonitorInfo.P_0x0028,
                MonitorInfo.P_0x0029, MonitorInfo.P_0x0401, MonitorInfo.P_0x0402, MonitorInfo.P_0x002A,
                MonitorInfo.P_0x002B, MonitorInfo.P_0x002C, MonitorInfo.P_0x002D,
                // 采集数据
                MonitorInfo.M_0x0502, MonitorInfo.M_0x0501, MonitorInfo.M_0x05E0, MonitorInfo.M_0x6589,
                MonitorInfo.M_0x05D1, MonitorInfo.M_0x0523,
                // 告警
                MonitorInfo.A_0x0204, MonitorInfo.A_0x0294, MonitorInfo.A_0x0295, MonitorInfo.A_0x0220,
                // 自定义
                MonitorInfo.C_CC0006, MonitorInfo.C_CC0007
        ),

        *//** 原位水质监测仪（COD+液位） *//*
        SR500_L_Y0_SYT(EquipmentType.SR500_L_Y0_SYT.getCode(),
                // 系统参数
                MonitorInfo.P_0x000B, MonitorInfo.P_0x0002, MonitorInfo.P_0x013A, MonitorInfo.P_0x013C,
                MonitorInfo.P_0x013CA, MonitorInfo.P_0x0118, MonitorInfo.P_0x0297, MonitorInfo.P_0x0298,
                MonitorInfo.P_0x0110, MonitorInfo.P_0x0165, MonitorInfo.P_0x0404, MonitorInfo.P_0x0028,
                MonitorInfo.P_0x0029, MonitorInfo.P_0x0401, MonitorInfo.P_0x0402, MonitorInfo.P_0x002A,
                MonitorInfo.P_0x002B, MonitorInfo.P_0x002C, MonitorInfo.P_0x002D,
                // 采集数据
                MonitorInfo.M_0x0502, MonitorInfo.M_0x0501, MonitorInfo.M_0x05E0, MonitorInfo.M_0x6588,
                MonitorInfo.M_0x05D1, MonitorInfo.M_0x0527, MonitorInfo.M_0x0520,
                // 告警
                MonitorInfo.A_0x0204, MonitorInfo.A_0x0297, MonitorInfo.A_0x0298, MonitorInfo.A_0x0220,
                // 自定义
                MonitorInfo.C_CC0002, MonitorInfo.C_CC0007
        ),
        *//** 雷达流量计*//*
        SE500_L_Y0(
                EquipmentType.SE500_L_Y0.getCode(),
                // 系统参数
                //MonitorInfo.P_0x013A, MonitorInfo.P_0x0002,MonitorInfo.P_0x013C,
                //MonitorInfo.P_0x1306,MonitorInfo.P_0x1307,MonitorInfo.P_0x0005,
                //MonitorInfo.P_0x0401,
                // 采集数据
                //MonitorInfo.M_0x0501,MonitorInfo.M_0x05D1,MonitorInfo.M_0x6598,
                //正向累计
                MonitorInfo.M_0x0590,
                //瞬时流量
                MonitorInfo.M_0x0592,
                //流速
                MonitorInfo.M_0x0593,
                //液位高度
                MonitorInfo.M_0x05D1
                //MonitorInfo.M_0x6500,MonitorInfo.M_0x6597
        ),
        *//** 窨井液位监测仪 *//*
        SY800_L_Y0(EquipmentType.SY800_L_Y0.getCode(),
                // 系统参数
                //MonitorInfo.P_0x000B, MonitorInfo.P_0x0002, MonitorInfo.P_0x013A, MonitorInfo.P_0x013C,
                //MonitorInfo.P_0x013CA, MonitorInfo.P_0x0110, MonitorInfo.P_0x0111, MonitorInfo.P_0x0165,
                //MonitorInfo.P_0x0404, MonitorInfo.P_0x0028, MonitorInfo.P_0x0029, MonitorInfo.P_0x0401,
               //MonitorInfo.P_0x0402, MonitorInfo.P_0x002A, MonitorInfo.P_0x002B, MonitorInfo.P_0x002C,
                //MonitorInfo.P_0x002D,
                // 采集数据
                MonitorInfo.M_0x05D1,
                MonitorInfo.M_0x05E0
                //MonitorInfo.M_0x0501,
                // 告警
                //MonitorInfo.A_0x0204, MonitorInfo.A_0x0220,
                // 自定义
                //MonitorInfo.C_CC0007
        );*/

        private String typeCode;
        private MonitorInfo[] monitorInfos;

        private EquipmentTypeMonitorInfo(String typeCode, MonitorInfo ...monitorInfos) {
            this.typeCode = typeCode;
            this.monitorInfos = monitorInfos;
        }

        public static MonitorInfo[] getMonitorsByType(String typeCode) {
            for (EquipmentTypeMonitorInfo typeMonitorInfo : EquipmentTypeMonitorInfo.values()) {
                if (typeMonitorInfo.getTypeCode().equals(typeCode)) {
                    return typeMonitorInfo.getMonitorInfos();
                }
            }
            return null;
        }
    }


    /**
     * 设备报警状态
     */
    @Getter
    public enum MqttAlarmType {
        REPORT("1", "故障上报"),
        RELIEVE("0", "故障解除");

        private String code;
        private String name;

        private MqttAlarmType(String code, String name) {
            this.code = code;
            this.name = name;
        }
    }

    /**
     * 报警现象
     */
    @Getter
    public enum MqttAlarm {
        /**
         * 通信故障告警
         */
        COMMUNICATION_FAILURE(0),
        /**
         * 上限越界告警
         */
        UPPER_BOUND(1),
        /**
         * 下限越界告警
         */
        LOWER_BOUND(2),
        /**
         * 设备故障告警
         */
        EQUIPMENT_FAILURE(3),
        /**
         * 电池低电量告警
         */
        LOW_BATTERY(4),
        /**
         * 状态量告警
         */
        STATE_QUANTITY(5);

        private Integer value;

        private MqttAlarm(Integer value) {
            this.value = value;
        }
    }

    /**
     * 阈值超限告警类型
     */
    @Getter
    public enum AlarmType {
        /** 超限告警 */
        OVERRUN("0"),
        /** 上下限越界告警 */
        UPPER_LOWER_BOUND("1"),
        /** 设备故障 */
        DEVICE_FAULT("10"),
        /** 跳变报警*/
        JUMP_CHANGE("2");

        private String value;

        private AlarmType(String value) {
            this.value = value;
        }
    }

    /**
     * 报警现象
     */
    @Getter
    public enum AlarmPhenomenon {
        /** 管网淤堵 */
        CLOGGING("0"),
        /** 电池低电量 */
        LOW_BATTERY("1"),
        /** 管网满管 */
        FULL_PACKAGE("2"),
        /** 电导率越界 */
        SPECIFIC_CONDUCTANCE_OVERSTEP("3"),
        /** 井盖异动 */
        ABNORMAL_MANHOLE_COVER("4"),
        /** COD越界 */
        COD_OVERSTEP("5"),
        /** 氨氮越界 */
        AMMONIA_NITROGEN_OVERSTEP("6"),
        /** 流量越界 */
        QUANTITY_FLOW_OVERSTEP("7"),
        /** 入流入渗 */
        INFLOW_INFILTRATION("8"),
        /** 设备掉线 */
        OFF_LINE("99");

        private String value;

        private AlarmPhenomenon(String value) {
            this.value = value;
        }
    }

    @Getter
    public enum ConfirmAlarmType {
        /** 待处理 */
        UNCONFIRMED(0),
        /** 处置中 */
        IN_DISPOSAL(1),
        /** 已清除 */
        CLEARED(2);

        private Integer value;

        ConfirmAlarmType(Integer value) {
            this.value = value;
        }
    }

    /**
     * 对外接口 微站的水质数据监测指标说明
     */
    @Getter
    public enum SiteMonitorInfo {
        SMI_302("PH值","302"),
        SMI_311("氨氮","311"),
        SMI_314("高锰酸盐指数","314"),
        SMI_313("总磷", "313"),
        SMI_465("浊度", "465"),
        SMI_315("溶解氧", "315"),
        SMI_463("电导率", "463"),
        SMI_301("水温", "301"),
        SMI_316("CODCr", "316"),
        SMI_446("总氮", "466"),
        SMI_726("电压", "726"),
        SMI_727("温度", "727"),
        SMI_728("湿度", "728");

        private String name;

        private String code;

        SiteMonitorInfo(String name, String code) {
            this.name = name;
            this.code = code;
        }

        public static SiteMonitorInfo getByCode(String code) {
            for (SiteMonitorInfo value : values()) {
                if (value.code.equals(code)) {
                    return value;
                }
            }
            return null;
        }
    }

    /**
     * 水类评判标准
     */
    @Getter
    public enum WaterStandard{

        GMSY_A(1,"高锰酸盐指数","Ⅰ类",0.00,2.00),
        GMSY_B(2,"高锰酸盐指数","Ⅱ类",2.00,4.00),
        GMSY_C(3,"高锰酸盐指数","Ⅲ类",4.00,6.00),
        GMSY_D(4,"高锰酸盐指数","Ⅳ类",6.00,10.00),
        GMSY_E(5,"高锰酸盐指数","Ⅴ类",10.00,15.00),
        GMSY_F(6,"高锰酸盐指数","劣Ⅴ类",15.00,9999.00),

        AD_A(1,"氨氮","Ⅰ类",0.00,0.15),
        AD_B(2,"氨氮","Ⅱ类",0.15,0.50),
        AD_C(3,"氨氮","Ⅲ类",0.50,1.00),
        AD_D(4,"氨氮","Ⅳ类",1.00,1.50),
        AD_E(5,"氨氮","Ⅴ类",1.50,2.00),
        AD_F(6,"氨氮","劣Ⅴ类",2.00,9999.00),

        ZL_A(1,"总磷","Ⅰ类",0.00,0.02),
        ZL_B(2,"总磷","Ⅱ类",0.02,0.10),
        ZL_C(3,"总磷","Ⅲ类",0.10,0.20),
        ZL_D(4,"总磷","Ⅳ类",0.20,0.30),
        ZL_E(5,"总磷","Ⅴ类",0.30,0.40),
        ZL_F(6,"总磷","劣Ⅴ类",0.40,9999.00);

        private Integer code;

        private String paramName;

        private String grade;

        private Double minValue;

        private Double maxValue;

        WaterStandard(Integer code,String paramName,String grade,Double minValue,Double maxValue){
            this.code = code;
            this.paramName = paramName;
            this.grade = grade;
            this.minValue = minValue;
            this.maxValue = maxValue;
        }

        //判断是否达标及现状
        public static SiteMonitorDataGetAllDto getValue(String paramName,String grade,String dataValue){
            SiteMonitorDataGetAllDto dto = new SiteMonitorDataGetAllDto();
            Integer nowJzmCode = 0;//现状编码
            Integer gradeCode = 0;//目标编码
            BigDecimal valueBig = new BigDecimal(dataValue);
            for (WaterStandard ws : values()){
                if (ws.getParamName().equals(paramName)){
                    BigDecimal minBig = new BigDecimal(ws.getMinValue().toString());
                    BigDecimal maxBig = new BigDecimal(ws.getMaxValue().toString());
                    int i = valueBig.compareTo(minBig);
                    int j = valueBig.compareTo(maxBig);
                    //判断现状
                    if (i>0 && j<=0){
                        dto.setNowJzm(ws.getGrade());//加入现状
                        dto.setCode(ws.getCode());//加入现状编码
                        nowJzmCode = ws.getCode();//标记现状编码
                    }
                    //判断当前目标等级的编码
                    if (ws.getGrade().equals(grade)){
                        gradeCode = ws.getCode();
                    }
                }
            }
            //dataValue为负数的情况
            if (nowJzmCode == 0){
                nowJzmCode = 1;
                dto.setNowJzm("Ⅰ类");
                dto.setCode(1);
            }
            //判断是否超标
            if (nowJzmCode > gradeCode){
                dto.setIfOverproof(true);
            }else {
                dto.setIfOverproof(false);
            }
            return dto;
        }
    }

    /**
     * 超图表名
     */
    @Getter
    public enum Smregister{

        SMDTV_1("池塘"),
        SMDTV_2("河道"),
        SMDTV_3("河道_point"),
        SMDTV_4("湖泊"),
        SMDTV_5("山塘"),
        SMDTV_6("水库"),
        SMDTV_7("泵站"),
        SMDTV_8("排口"),
        SMDTV_9("微站"),
        SMDTV_10("溢流井"),
        SMDTV_11("闸口"),
        SMDTV_12("溢流井液位"),
        SMDTV_13("窨井"),
        SMDTV_14("污水泵站"),
        SMDTV_15("水质监测点"),
        SMDTV_16("生活小区"),
        SMDTV_17("其他类"),
        SMDTV_18("排水户"),
        SMDTV_19("农村水终端");

        private String name;

        Smregister(String name){
            this.name = name;
        }
    }


}
